package pathways.Database.Specialized.Visual;

/**
 * Title:        Pathways
 * Description:  Pure Java version of the Pathways Project.
 * Copyright:    Copyright (c) 2002
 * Company:      Ants Technologies
 * @author Veejay Sani
 * @version 1.0
 */
import java.awt.Frame;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.sql.ResultSet;
import java.sql.SQLException;

import javax.swing.AbstractListModel;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.SwingConstants;

import pathways.CCompound;
import pathways.Database.Implementation.CDatabase;
import pathways.util.CUtil;
import pathways.util.Debug.CDebug;

public class CSearchCompound extends JDialog implements KeyListener, ActionListener
{
  
  JLabel lblCompound = new JLabel();
  JTextField txtCompound = new JTextField();
  JScrollPane jScrollPane1 = new JScrollPane();
  JList lstCmpds = new JList();
  JButton cmdOK = new JButton();
  JButton cmdCancel = new JButton();
  // myvars
  CMyListModel mdl;
  private boolean bAllowNew;
  private CDatabase db;
  private CCompound selectedCmpd;
  private int filter;
  
  public static int FILTER_NONE = 0;
  public static int FILTER_SUBSTRATES = 1;
  public static int FILTER_ENZYMES = 2;
  public static int FILTER_PRODUCTS = 3;
  public static int FILTER_SUBSANDPRODS = 4;
  
  public CSearchCompound(boolean allowNew, Frame owner, CDatabase database, int searchFilter)
  {
    // filter = 0 -> all compounds
    // filter = 1 -> substrates only
    // filter = 2 -> enzymes only
    // filter = 3 -> products
    // filter = 4 -> substrates & products
    
    super(owner,true);
    
    String title = "";
    
    if (allowNew)
       title = "Search/New Compound";
    else
       title = "Search Compound";
    
    super.setTitle(title);
    
    try
    {
      jbInit();
    }
    catch(Exception e)
    {
      e.printStackTrace();
    }
    
    bAllowNew = allowNew;
    filter = searchFilter;
    db = database;
    
    this.txtCompound.addKeyListener(this);
    this.cmdOK.addActionListener(this);
    this.cmdCancel.addActionListener(this);
    
    setSize(250,250);
  }
  
  public void keyTyped(KeyEvent e)
  {

  }
  
  public void keyPressed(KeyEvent e)
  {

  }
  
  public void keyReleased(KeyEvent e)
  {
    if (e.getKeyCode() == KeyEvent.VK_ENTER)
    {
      String cmpdName = this.txtCompound.getText();
      
      ResultSet r = db.getSelect().getCompoundsMatchingName(cmpdName,filter);
      
      try{
        if (!r.next())
        {
          JOptionPane.showMessageDialog(this,"No compound found.","",JOptionPane.WARNING_MESSAGE);  
        }
      } catch(SQLException sqle){}
      
      mdl = new CMyListModel(r);
      this.lstCmpds.setModel(mdl);
    }
  }

  public boolean searchFor(String cmpdName)
  {
    ResultSet r = db.getSelect().getCompoundsMatchingName(cmpdName,filter);
    
    this.txtCompound.setText(cmpdName);
        
    mdl = new CMyListModel(r);
    this.lstCmpds.setModel(mdl);
    
    try{
      return r.next();
    } catch(SQLException sqle){
      return false;
    }
  }  
  public CCompound getSelectedCompound()
  {
    return selectedCmpd;  
  }
  
  public void actionPerformed(ActionEvent e)
  {
    if (e.getActionCommand().equals("OK"))
    {
      OK();  
    }
    else
    {
      Cancel();
    }
    
  }
  
  private void OK()
  {
    int index = this.lstCmpds.getSelectedIndex();
    
    if (index >= 0)
    {
      selectedCmpd = this.mdl.getCompound(index);
      this.hide();
    }
    else
    {      
      // try finding if the user didn't bother to select a compound  
      CCompound c = selectForUser();
      
      if (c != null)
      {
        selectedCmpd = c;
        this.hide();
        return;
      }
      
      // well if we are here in the code then either the user needs
      // to select 
      if (this.txtCompound.getText().length() > 0 && bAllowNew)
      {
        // prompt to add a new compound        
        if (JOptionPane.showConfirmDialog(this,"Do you want to create a new compound?","New Compound",JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION);
        {
          
          // add a new compound and close the screen
          CCompound compound = new CCompound(this.txtCompound.getText(),0);
          
          String ECNO = JOptionPane.showInputDialog(this,"Enter the ECNO for the compound");
          
          if (ECNO == null)
             ECNO = "";
          
          compound.setECNO(ECNO);
                              
          try {
              db.getConnection().beginTrans();
          } catch (SQLException excep)
          {
            CDebug.println(this,"OK() - Unable to start a transaction");  
          }
          
          if (compound.save(db))
          {
            selectedCmpd = compound;
            
            try {
                db.getConnection().commitTrans();
            } catch(SQLException excep)
            {
              CDebug.println(this,"OK() - Unable to start a transaction");  
            }
            
            this.hide();
            return;
          }
          else
          {
            try {
                db.getConnection().rollbackTrans();
            } catch (SQLException excep)
            {
              CDebug.println(this,"OK() - Unable to start a transaction");  
            }
            
            JOptionPane.showMessageDialog(this,"Unable to create a new compound.");
            CDebug.println(this,"OK() Unable to create a new compound.");  
            return;
          }
        }
      }
      else
      {
        JOptionPane.showMessageDialog(this,"Please select a compound.");
        return;
      } 
    }
  }
  
  private CCompound selectForUser()
  {
    if (this.txtCompound.getText().length() > 0)
    {
      ResultSet r = db.getSelect().getCompound(this.txtCompound.getText());
      
      try {
        if (r.next())
        {
          // found it
          return(new CCompound(r.getString(1),r.getLong(3)));
        }
      } catch(SQLException e) {
        CDebug.println(this,"selectForUser() - Unable to read compound.  User did not select any index so tried to see if text entered in DB but failed.  Text Entered: " + this.txtCompound.getText() + " Exception: " + e.toString());
        return null;
      }
    }
    
    return null;    
  }
  
  private void Cancel()
  {
    selectedCmpd = null;
    this.hide();
  }
  
  private void jbInit() throws Exception
  {
    lblCompound.setHorizontalAlignment(SwingConstants.RIGHT);
    lblCompound.setText("Compound:");
    lblCompound.setBounds(new Rectangle(2, 11, 72, 17));
    this.getContentPane().setLayout(null);
    txtCompound.setBounds(new Rectangle(77, 14, 149, 19));
    jScrollPane1.setBounds(new Rectangle(78, 49, 150, 138));
    cmdOK.setText("OK");
    cmdOK.setBounds(new Rectangle(79, 195, 57, 24));

    cmdCancel.setBounds(new Rectangle(143, 195, 86, 24));
    cmdCancel.setText("Cancel");
    this.getContentPane().add(txtCompound, null);
    this.getContentPane().add(jScrollPane1, null);
    this.getContentPane().add(cmdOK, null);
    jScrollPane1.getViewport().add(lstCmpds, null);
    this.getContentPane().add(cmdCancel, null);
    this.getContentPane().add(lblCompound, null);
  }


}

class CMyListModel extends AbstractListModel
{  
  public CMyListModel(ResultSet r)
  {
    data = r; 
  }
  
  public void setData(ResultSet r)
  {
    data = r;  
  }
  
  public ResultSet getData()
  {
    return data;  
  }
  
  public Object getElementAt(int index)
  {
    try {
        data.absolute(index+1);
        return data.getString(2);
    } catch(SQLException e) {
      CDebug.println(this, "getElementAt() - Access to element # " + (index+1) + " failed. Exception: " + e.toString());
      return null;
    }
  }
  
  public int getSize()
  { 
    try {     
        return CUtil.getResultSetRowCount(data);
    } catch(SQLException e) {
      CDebug.println(this, "getSize(). Exception: " + e.toString());
      return 0;
    }
  }
  
  public CCompound getCompound(int index)
  {
    try{
      data.absolute(index + 1);
      return (new CCompound(data.getString(2),data.getLong(1)));
    } catch(SQLException e) {
      CDebug.println(this, "getCompound(). Exception: " + e.toString());
      return null;
    }
  }
  
  private ResultSet data;
}